<?php
// +----------------------------------------------------------------------
// | 中犇单商户
// +----------------------------------------------------------------------
// | Copyright (c) 2019-2021 中犇科技 All rights reserved.
// +----------------------------------------------------------------------


namespace app\operation\model;

use think\Model as ThinkModel;


/**
 * 优惠券领取模型
 * @package app\operation\model
 */
class CouponRecord extends ThinkModel
{
    // 设置当前模型对应的完整数据表名称
    protected $table = '__OPERATION_COUPON_RECORD__';

    // 自动写入时间戳
    protected $autoWriteTimestamp = true;

    /**
     *
     * @return \think\model\relation\HasOne
     */
    public function operation_coupon()
    {
        return $this->hasOne('OperationCoupon', 'c_id');
    }

    /**
     * 优惠券列表
     * @param $userId
     * @param $type
     * @author  风轻云淡
     * @return array|false|\PDOStatement|string|\think\Collection
     */
    public function get_coupon_list($userId, $type, $orderPrice)
    {
        $where[] = ['cr.user_id', 'eq', $userId]; 
        $nowTime = time();
        $sort = "cr.end_time desc";
        switch ($type){
            case 1: //全部
                break;
            case 2: //待使用
                $where[] = ['cr.status', 'eq', 1];
                $where[] = ['cr.start_time', 'lt', $nowTime];
                $where[] = ['cr.end_time', 'gt', $nowTime];
                break;
            case 3: //已使用
                $where[] = ['cr.status', 'eq', 3];       
                break;
            case 4: //已过期
                $where[] = ['cr.status', 'eq', 4];
                $where[] = ['cr.end_time', 'lt', $nowTime];
                break;
        }
        if($orderPrice > 0){
            $sort = "oc.money desc";
            $where[] = ['oc.min_order_money', 'elt', $orderPrice];
        }
        $couponList = CouponRecord::alias("cr")->join("__OPERATION_COUPON__ oc", "oc.id=cr.cid")
                        ->field("cr.id,cr.end_time,cr.status,oc.money,oc.min_order_money,oc.name as coupon_name,oc.cid,oc.goods_id,oc.content")
                        ->where($where)
                        ->order($sort)
                        ->select();

        return $couponList;        
    }

    /**
     * 优惠券详情
     * @param $where
     * @author  风轻云淡
     * @return array|false|null|\PDOStatement|string|ThinkModel
     */
    public function get_user_coupon($where)
    {
        $coupon_detail = CouponRecord::alias("cr")->join("__OPERATION_COUPON__ oc", "oc.id=cr.cid")
            ->where($where)
            ->field("cr.id,cr.end_time,cr.status,cr.end_time,oc.money,oc.min_order_money,oc.name as coupon_name,oc.content")->find();
        if ($coupon_detail) {
            $coupon_detail['content'] = $coupon_detail['content'] ? $coupon_detail['content'] : "";
            $coupon_detail['end_time'] = date("Y-m-d H:i", $coupon_detail['end_time']);
        }
        return $coupon_detail;
    }

    /**
     * 修改优惠券是否过期
     * @param $userId
     * @author  风轻云淡
     * @return int|string
     */
    public function edit_coupon($userId)
    {
        $where[] = ['user_id', 'eq', $userId];
        $where[] = ['status', 'eq', 1];
        $where[] = ['end_time', 'lt', time()];
        $res = CouponRecord::where($where)->update(['status' => 4]);
        return $res;
    }

    /**
     * 获得可用优惠券
     * @param $userId  //用户id
     * @param $orderPrice //订单金额
     * @param $category //商品分类价格统计[{cid:1,money:5},{cid:2,money:10}]
     * @param $goods //商品价格统计[{goods_id :1,money:5},{goods_id :2,money:10}]
     * @author 晓风<215628355@qq.com> 2021年10月20日20:44:53 重构，原有方法已废弃
     * @return array|false|null|string|ThinkModel
     */
    public static function get_best_coupon(int $userId,float $orderPrice,array $category = [], array $goods = [])
    {
        $nowTime = time();
        $where[] = ['cr.user_id', 'eq', $userId];
        $where[] = ['cr.status', 'eq', 1];      
        $where[] = ['cr.start_time', 'elt', $nowTime];
        $where[] = ['cr.end_time', 'egt', $nowTime];
        
        //默认的情况是查询全品类劵
        $whereOr[] = "(oc.cid = 0 AND oc.goods_id = 0 AND oc.min_order_money <= $orderPrice )";
     
        //绑定商品分类判断
        //查询品类优惠券
        foreach($category as $item){        
            $id = $item["cid"];
            $money = $item['money'];
            if(!is_numeric($id) || !is_numeric($money)){
                throw new \Exception("category in cid or money is not fund");
            }
            $pids = \app\goods\model\Category::getParentsId($id);
            $ids = implode(",",$pids);
            $whereOr[] = "(oc.cid in ( $ids ) AND oc.goods_id = 0 AND oc.min_order_money <= $money  )";
        }     
        //绑定商品ID判断
        //查询单品优惠券
        foreach($goods as $item){
            $id = $item["goods_id"];
            $money = $item['money'];
            if(!is_numeric($id) || !is_numeric($money)){
                throw new \Exception("category in goods_id or money is not fund");
            }
            $whereOr[] = "(oc.goods_id = $id AND oc.cid = 0 AND oc.min_order_money <= $money  )";
        }        
        
        $couponInfo = CouponRecord::alias("cr")->join("__OPERATION_COUPON__ oc", "oc.id=cr.cid")
            ->where($where)
            ->where(implode(" OR ",$whereOr))
            ->field("cr.id,oc.name,oc.money,oc.min_order_money,cr.end_time,oc.content")
            ->order("money desc")      
            ->select();
        return $couponInfo;
    }


    /**
     * 获得可用优惠券
     * @param $userId  //用户id
     * @param $orderPrice //订单金额
     * @param $category //商品分类价格统计[{cid:1,money:5},{cid:2,money:10}]
     * @param $goods //商品价格统计[{goods_id :1,money:5},{goods_id :2,money:10}]
     * @author 晓风<215628355@qq.com> 2021年10月20日20:44:53 重构，原有方法已废弃
     */
    public static function get_best_coupon_new(int $userId,float $orderPrice,array $category = [], array $goods = [])
    {

        return self::get_best_coupon($userId, $orderPrice, $category, $goods);
    }
        
     /**
     * 发放优惠券
     * @author 晓风 2021年8月11日22:48:15
     * @param int $user_id
     * @param int $couponId
     */
    public static function sendUserCoupon(int $user_id,int $couponId , int $method = null){    
        
        $check = self::checkCoupon($user_id, $couponId);
        if($check > 0){
            throw new \Exception("该会员有未使用的优惠券");  
        }   
        $map[] = ['id', '=', $couponId];      
        $map[] = ['is_delete', 'eq', 0];
        if(null !== $method){
            $map[] = ['method', 'eq', $method];
        }        
        $coupon = Coupon::where($map)->field('id,valid_day,cid,goods_id,last_stock,stock,min_order_money,money,content')->lock(true)->find();
        if(!$coupon){
            throw new \Exception("该优惠券不支持发放");
        }  
               
        if($coupon['last_stock']<=0 && $coupon['stock'] > 0){
            throw new \Exception("已经发放完了");              
        }     
        self::saveUserCoupon($coupon, $user_id);
        return $coupon;
    }
    
     /**
     * 领取优惠券
     * @author 晓风 2021年8月11日22:48:15
     * @param int $user_id
     * @param int $couponId
     */
    public static function receiveCoupon(int $user_id,int $couponId){            
        $check = self::checkCoupon($user_id, $couponId);
        if($check > 0){
            throw new \Exception("请勿重复领取");  
        }         
        $map[] = ['id', '=', $couponId];
        $map[] = ['status', '=', 1];
        $map[] = ['end_time', '>', time()];
        $map[] = ['last_stock', '>', 0];
        $map[] = ['is_delete', 'eq', 0];        
        $coupon = Coupon::where($map)->field('id,valid_day,cid,goods_id')->lock(true)->find();
        if (!$coupon) {
            exception('优惠券已经被领取完了');
        }     
        self::saveUserCoupon($coupon, $user_id);
        return $coupon;
    }
    
    /**
     * 执行保存优惠券
     * @param \app\operation\model\Coupon $coupon
     * @param int $user_id
     * @return boolean
     * @throws \Exception
     */
    private static function saveUserCoupon(Coupon $coupon,int $user_id){      
        self::unsetTime();   
        $res = self::create([
            'cid' => $coupon["id"],
            'user_id' => $user_id,
            'start_time' => time(),
            'end_time' => strtotime("+". $coupon["valid_day"] . " day"),
            'status' => 1,
            'goods_id' => $coupon["goods_id"]
        ]);
        if(!$res){
            throw new \Exception("发放失败");
        }
        Coupon::where('id',$coupon["id"])->setDec("last_stock");
        return true;
    }
    
     /**
     * 判断是否可以领取优惠券
     * @author 晓风<215628355@qq.com>
     * @param int $user_id
     * @param int $couponId
     */
    public static function checkCoupon(int $user_id,int $couponId){
        $count = self::where('user_id',$user_id)->where('cid' , $couponId )->where("status","in",[1,2])->where("end_time","gt",time())->count();
        return $count > 0 ? 1 : 0;
    }
    /**
     * 执行过期销毁
     * @author 晓风<215628355@qq.com>
     * @return int
     */
    public static function unsetTime($userId = 0){
        $map[] = ["status","=",1];
        $map[] = ["end_time","lt", time()];
        if($userId > 0){
            $map[] = ["user_id","=",$userId];  
        }
        return  self::where($map)->update(['status'=>4]);
    }
}
